package arXiv;

/*
 * SearchGui.java
 * A GUI for the user to input keywords for the reference search
 */
 
import javax.swing.*;  
import javax.swing.text.*;      

import java.awt.*;
import java.awt.event.*;

import java.net.*;
import java.io.*;

import java.util.*;


public class SearchGui implements ActionListener {

		JTextField keywordField = new JTextField(20);
        JTextField authorField = new JTextField(20);  
		JTextField titleField = new JTextField(20);
        JTextField numResultsField = new JTextField("2",3);
        JButton searchButton = new JButton("Search arXiv");
        JEditorPane editorPane = new JEditorPane();
		JTextArea textArea = new JTextArea(5, 20);
   
        String queryString = "";	// api search query
		boolean isquery = false;	// whether search terms have been entered
     
    public SearchGui() {
        //Create and set up the window.
        JFrame frame = new JFrame("My Reference Finder");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
		//Create the menu bar - this isn't used right now
        JMenuBar menuBar = new JMenuBar();
        menuBar.setOpaque(true);
        menuBar.setPreferredSize(new Dimension(200, 20));
        frame.setJMenuBar(menuBar);   
        
        //Create a panel to input search keywords 
		JPanel searchPanel = new JPanel();	
    
        //Add some search boxes
        //This should probably be done in a more organised way
                
        JLabel keywordLabel = new JLabel("Keyword:");
        keywordLabel.setLabelFor(keywordField);
        
        JLabel authorLabel = new JLabel("Author:");
        authorLabel.setLabelFor(authorField);
        
		JLabel titleLabel = new JLabel("Title:");
        titleLabel.setLabelFor(titleField);
		
        JLabel numResultsLabel = new JLabel("No. Results:");
        numResultsLabel.setLabelFor(numResultsField);
        
        //Lay out the text fields and the labels.
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        searchPanel.setLayout(gridbag);

        JLabel[] labels = {keywordLabel, authorLabel, titleLabel};
        JTextField[] textFields = {keywordField, authorField, titleField};
        addLabelTextRows(labels, textFields, gridbag, searchPanel);
		
		// Lay out more text fields
		c.gridwidth = GridBagConstraints.RELATIVE; 
        c.fill = GridBagConstraints.NONE;      
        c.weightx = 0.0;                       
        searchPanel.add(numResultsLabel,c);

        c.gridwidth = GridBagConstraints.REMAINDER;     //end row
        c.fill = GridBagConstraints.NONE;
		c.anchor = GridBagConstraints.LINE_START;
        c.weightx = 1.0;
		searchPanel.add(numResultsField,c);
       
        c.gridwidth = GridBagConstraints.REMAINDER; //last
        c.anchor = GridBagConstraints.CENTER;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.0;
        
        searchPanel.add(searchButton, c);
        searchButton.addActionListener(this);

        
        // border for the search panel 
        searchPanel.setBorder(
                BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder("Search Fields"),
                                BorderFactory.createEmptyBorder(5,5,5,5)));
                                
	     // panel to display the search results 
        JPanel feedPanel = new JPanel(new BorderLayout());
        
        // border for the feed panel 
        feedPanel.setBorder(
                BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder("Query result (for testing)"),
                                BorderFactory.createEmptyBorder(5,5,5,5)));
        
        
        // editor pane for displaying results of query
		editorPane.setEditable(false);
			
		//Put the editor pane in a scroll pane
		JScrollPane editorScrollPane = new JScrollPane(editorPane);
		editorScrollPane.setVerticalScrollBarPolicy(
		                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		editorScrollPane.setPreferredSize(new Dimension(250, 145));
		editorScrollPane.setMinimumSize(new Dimension(10, 10)); 
			
		feedPanel.add(editorScrollPane);
		
		// Pane for displaying entries
		JPanel resultsPanel = new JPanel(new BorderLayout());
		
		// border for the results panel 
        resultsPanel.setBorder(
                BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder("Display results"),
                                BorderFactory.createEmptyBorder(5,5,5,5)));
        
		// text area for displaying results of query
		textArea.setEditable(false);
			
		//Put the text area in a scroll pane
		JScrollPane textScrollPane = new JScrollPane(textArea);
		textScrollPane.setVerticalScrollBarPolicy(
		                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		textScrollPane.setPreferredSize(new Dimension(250, 145));
		textScrollPane.setMinimumSize(new Dimension(10, 10)); 
			
		resultsPanel.add(textArea);
		
		
		// add in all panes
        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.add(searchPanel, 
                     BorderLayout.PAGE_START);
        contentPane.add(feedPanel,
                     BorderLayout.CENTER);
		contentPane.add(resultsPanel, BorderLayout.PAGE_END);
        
        frame.getRootPane().setDefaultButton(searchButton);
		frame.setContentPane(contentPane);

        //Display the window.
        frame.pack();
        // Centre on screen
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    // layout stuff
    private static void addLabelTextRows(JLabel[] labels,
                                  JTextField[] textFields,
                                  GridBagLayout gridbag,
                                  Container container) {
        GridBagConstraints c = new GridBagConstraints();
        c.anchor = GridBagConstraints.EAST;
        int numLabels = labels.length;

        for (int i = 0; i < numLabels; i++) {
            c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
            c.fill = GridBagConstraints.NONE;      //reset to default
            c.weightx = 0.0;                       //reset to default
            container.add(labels[i], c);

            c.gridwidth = GridBagConstraints.REMAINDER;     //end row
            c.fill = GridBagConstraints.HORIZONTAL;
            c.weightx = 1.0;
            container.add(textFields[i], c);
        }
    }
    
    // on button click 
    public void actionPerformed(ActionEvent e) {
    	
    	displayResults();
    	
    }

    
    private String getQueryString() {
	
	// TODO: check AND and OR multiple word cases
        
        queryString = "http://export.arxiv.org/api/query?search_query=";
        isquery = false;			
		
		// add inserted keywords to query
		String keyText = keywordField.getText();
		if (!keyText.equals("")) addtoURL(keyText,"all");
		String authorText = authorField.getText();
		if (!authorText.equals("")) addtoURL(authorText,"au");
		String titleText = titleField.getText();
		if (!titleText.equals("")) addtoURL(titleText,"ti");
			
		if (!isquery) {
			// no keywords entered, go to the default page
			queryString = "http://export.arxiv.org/api/";
		}
		else {
			queryString += "&start=0&max_results=" + numResultsField.getText();
		}
				     
        return queryString;
        
    }
	
	public void addtoURL (String text, String prefix) {
	
	if (isquery){
		queryString += "+AND+";
	}
	queryString += prefix + ":";
	
	//format text with a tokenizer to get rid of spaces
	// TODO: use .split() instead
	// check this
	StringTokenizer st = new StringTokenizer(text);
    queryString += "%22" + st.nextToken();
	while (st.hasMoreTokens()) {
         queryString += "+" + st.nextToken();
    }
	queryString += "%22";
		
	isquery = true;
	}
    
    public void displayResults () {
    		String queryString = getQueryString();
    		System.out.println(queryString);
    		URL queryURL = null;
    		
    		try {
    			queryURL = new URL(queryString);
    		} catch (MalformedURLException e) {
		   	     System.err.println("URL didn't work");
		    }
		   
    		if (queryURL != null) {
				try {
					BufferedReader in = new BufferedReader(
       			new InputStreamReader(
        			queryURL.openStream()));

   				String inputLine;

  				while ((inputLine = in.readLine()) != null){
      			//System.out.println(inputLine);
				}
   				in.close();
				
				// output unparsed results
				editorPane.setPage(queryURL);
				
				// parse results
				AtomParser myParser = new AtomParser(queryURL); 
				
				myParser.doParsing();
				
				// display results
				textArea.setText(myParser.myParseOutput.display());

					
				} catch (IOException e) {
					System.err.println("Attempted to read a bad URL " + queryString);
				}
		    } else {
			    System.err.println("Something wrong");
			}	
	
	}
    

			

    public static void main(String[] args) throws Exception {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                SearchGui myGUI = new SearchGui();
            }
        });
    }
}
